package cn.ruanyun.backInterface.modules.fadada.serviceimpl;

import cn.ruanyun.backInterface.common.constant.CommonConstant;
import cn.ruanyun.backInterface.common.enums.AudienceTypeEnum;
import cn.ruanyun.backInterface.common.enums.PlatformTypeEnum;
import cn.ruanyun.backInterface.common.enums.PushTypeEnum;
import cn.ruanyun.backInterface.common.utils.*;
import cn.ruanyun.backInterface.common.vo.PageVo;
import cn.ruanyun.backInterface.common.vo.Result;
import cn.ruanyun.backInterface.modules.base.pojo.DataVo;
import cn.ruanyun.backInterface.modules.base.pojo.User;
import cn.ruanyun.backInterface.modules.base.service.mybatis.IUserService;
import cn.ruanyun.backInterface.modules.business.goodCategory.service.IGoodCategoryService;
import cn.ruanyun.backInterface.modules.fadada.dto.PushOneElectronicContractDto;
import cn.ruanyun.backInterface.modules.fadada.dto.PushTwoElectronicContractDto;
import cn.ruanyun.backInterface.modules.fadada.mapper.ElectronicContractMapper;
import cn.ruanyun.backInterface.modules.fadada.pojo.ElectronicContract;
import cn.ruanyun.backInterface.modules.fadada.pojo.MyContractSigning;
import cn.ruanyun.backInterface.modules.fadada.pojo.MyContractSigningCheck;
import cn.ruanyun.backInterface.modules.fadada.service.IElectronicContractService;
import cn.ruanyun.backInterface.modules.fadada.service.IMyContractSigningCheckService;
import cn.ruanyun.backInterface.modules.fadada.service.IMyContractSigningService;
import cn.ruanyun.backInterface.modules.fadada.service.IfadadaService;
import cn.ruanyun.backInterface.modules.fadada.vo.ElectronicContractVo;
import cn.ruanyun.backInterface.modules.jpush.dto.JpushDto;
import cn.ruanyun.backInterface.modules.jpush.service.IJpushService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fadada.sdk.client.FddClientBase;
import com.fadada.sdk.client.FddClientExtra;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 电子合同接口实现
 * @author z
 */
@Slf4j
@Service
@Transactional
public class IElectronicContractServiceImpl extends ServiceImpl<ElectronicContractMapper, ElectronicContract> implements IElectronicContractService {


    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private IGoodCategoryService goodCategoryService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IMyContractSigningService myContractSigningService;

    @Autowired
    private IJpushService jpushService;

    @Autowired
    private IMyContractSigningCheckService myContractSigningCheckService;

    @Override
    public Result<Object> insertOrUpdateElectronicContract(ElectronicContract electronicContract) {

        if (ToolUtil.isEmpty(electronicContract.getId())) {

            electronicContract.setCreateBy(securityUtil.getCurrUser().getId());
        }else {

            electronicContract.setUpdateBy(securityUtil.getCurrUser().getId());
        }

        this.saveOrUpdate(electronicContract);

        return new ResultUtil<>().setSuccessMsg("添加或者更新模板合同成功！");
    }

    /**
     * 移除电子合同
     *
     * @param ids ids
     * @return Object
     */
    @Override
    public Result<Object> removeElectronicContract(String ids) {

        this.removeByIds(ToolUtil.splitterStr(ids));

        return new ResultUtil<>().setSuccessMsg("移除成功！");
    }

    /**
     * 获取电子合同列表
     *
     * @param pageVo 分页
     * @return 电子合同vo
     */
    @Override
    public Result<DataVo<ElectronicContractVo>> getElectronicContractList(PageVo pageVo) {


        Page<ElectronicContract> electronicContractPage = this.page(PageUtil.initMpPage(pageVo), Wrappers.<ElectronicContract>lambdaQuery()
        .orderByDesc(ElectronicContract::getCreateTime));

        if (ToolUtil.isEmpty(electronicContractPage.getRecords())) {

            return new ResultUtil<DataVo<ElectronicContractVo>>().setErrorMsg(201, "暂无数据");
        }

        DataVo<ElectronicContractVo> result = new DataVo<>();

        result.setDataResult(electronicContractPage.getRecords().parallelStream().flatMap(electronicContract -> {

            ElectronicContractVo electronicContractVo = new ElectronicContractVo();
            ToolUtil.copyProperties(electronicContract, electronicContractVo);
            electronicContractVo.setGoodCategoryName(goodCategoryService.getGoodCategoryName(electronicContract.getGoodCategoryId()));

            return Stream.of(electronicContractVo);

        }).collect(Collectors.toList())).setTotalSize(electronicContractPage.getTotal())
                .setCurrentPageNum(electronicContractPage.getCurrent())
                .setTotalPage(electronicContractPage.getPages());

        return new ResultUtil<DataVo<ElectronicContractVo>>().setData(result, "获取合同模板成功！");
    }

    @Override
    public Result<Object> pushElectronicContract(PushOneElectronicContractDto pushElectronicContractDto) {

        return Optional.ofNullable(this.getById(pushElectronicContractDto.getId())).map(electronicContract -> {

            //上传法大大模板
            FddClientBase base = new FddClientBase(CommonConstant.F_APP_ID,CommonConstant.F_APP_SECRET,CommonConstant.F_VERSION,CommonConstant.F_HOST);

            //模板公网下载地址
            String docUrl = electronicContract.getDocUrl();

            //模板id
            String templateId = CommonUtil.getRandomNum();

            String result = base.invokeUploadTemplate(templateId, null, docUrl);

            log.info(result);

            if ("1".equals(JSONObject.parseObject(result).getString("code"))) {

                //填充数据
                return generateContract(pushElectronicContractDto, templateId, electronicContract.getGoodCategoryId());
            }else {

                log.info(JSONObject.parseObject(result).getString("result"));
                return new ResultUtil<>().setErrorMsg(JSON.parseObject(result).getIntValue("code")
                ,JSONObject.parseObject(result).getString("msg"));
            }

        }).orElse(new ResultUtil<>().setErrorMsg(203, "暂无订单数据！"));
    }

    @Override
    public Result<Object> viewClientExtra(String id) {


        FddClientExtra extra = new FddClientExtra(CommonConstant.F_APP_ID,CommonConstant.F_APP_SECRET,CommonConstant.F_VERSION, CommonConstant.F_HOST);
       if (ToolUtil.isNotEmpty(id)) {

           return Optional.ofNullable(myContractSigningCheckService.getById(id))
                   .map(myContractSigningCheck -> new ResultUtil<>().setData(extra.invokeViewPdfURL(myContractSigningCheck.getContractId()), "获取查看合同地址成功！"))
                   .orElse(new ResultUtil<>().setErrorMsg(203, "不存在"));
       }else {

          return Optional.ofNullable(myContractSigningCheckService.getOne(Wrappers.<MyContractSigningCheck>lambdaQuery()
           .eq(MyContractSigningCheck::getCreateBy, securityUtil.getCurrUser().getId())
           .orderByDesc(MyContractSigningCheck::getCreateTime)
           .last("limit 1")))
           .map(myContractSigningCheck -> new ResultUtil<>().setData(extra.invokeViewPdfURL(myContractSigningCheck.getContractId()), "获取查看合同地址成功！"))
                  .orElse(new ResultUtil<>().setErrorMsg(203, "不存在"));

       }
    }

    @Override
    public Result<Object> invokeDownloadPdf(String id) {

        FddClientExtra extra = new FddClientExtra(CommonConstant.F_APP_ID,CommonConstant.F_APP_SECRET,CommonConstant.F_VERSION, CommonConstant.F_HOST);
        if (ToolUtil.isNotEmpty(id)) {

            return Optional.ofNullable(myContractSigningCheckService.getById(id))
                    .map(myContractSigningCheck -> new ResultUtil<>().setData(extra.invokeDownloadPdf(myContractSigningCheck.getContractId()), "获取查看合同地址成功！"))
                    .orElse(new ResultUtil<>().setErrorMsg(203, "不存在"));
        }else {

            return Optional.ofNullable(myContractSigningCheckService.getOne(Wrappers.<MyContractSigningCheck>lambdaQuery()
                    .eq(MyContractSigningCheck::getCreateBy, securityUtil.getCurrUser().getId())
                    .orderByDesc(MyContractSigningCheck::getCreateTime)
                    .last("limit 1")))
                    .map(myContractSigningCheck -> new ResultUtil<>().setData(extra.invokeDownloadPdf(myContractSigningCheck.getContractId()), "获取查看合同地址成功！"))
                    .orElse(new ResultUtil<>().setErrorMsg(203, "不存在"));

        }
    }


    public Result<Object> generateContract(PushOneElectronicContractDto pushElectronicContractDto, String templateId, String categoryId) {


            MyContractSigning myContractSigningNew = new MyContractSigning();
            myContractSigningNew.setTemplateId(templateId)
                    .setBeginYear(pushElectronicContractDto.getBeginYear())
                    .setBeginMonth(pushElectronicContractDto.getBeginMonth())
                    .setBeginDay(pushElectronicContractDto.getBeginDay())
                    .setEndYear(pushElectronicContractDto.getEndYear())
                    .setEndMonth(pushElectronicContractDto.getEndMonth())
                    .setEndDay(pushElectronicContractDto.getEndDay())
                    .setCouponMoney(pushElectronicContractDto.getCouponMoney())
                    .setCreateBy(userService.getOne(Wrappers.<User>lambdaQuery()
                    .eq(User::getMobile, pushElectronicContractDto.getPhone()))
                    .getId());

            if ("婚宴酒店".equals(goodCategoryService.getGoodCategoryName(categoryId))) {

                myContractSigningNew.setTotalMoney(pushElectronicContractDto.getTotalMoney())
                        .setUserBuyMoney(pushElectronicContractDto.getUserBuyMoney())
                        .setDepositMoney(pushElectronicContractDto.getDepositMoney());
            }

            myContractSigningService.save(myContractSigningNew);

            //推送逻辑
            JpushDto jpushDto = new JpushDto();
            jpushDto.setPushType(PushTypeEnum.ELECTRONIC_CONTRACT)
                    .setAudienceType(AudienceTypeEnum.TAG)
                    .setTitle("电子合同")
                    .setContent("你有一份电子合同需要签署")
                    .setPlatformType(PlatformTypeEnum.ALL)
                    .setUserId(userService.getOne(Wrappers.<User>lambdaQuery()
                            .eq(User::getMobile, pushElectronicContractDto.getPhone()))
                            .getId());
            jpushService.pushArticleToUser(jpushDto);

            return new ResultUtil<>().setSuccessMsg("推送电子合同成功！");
    }

}